﻿// Copyright Microsoft

using System;
using System.Activities.Presentation.View;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Activities.Presentation.Model;
using Microsoft.Samples.SqlServer.ExtensionMethods;
using System.Data.SqlClient;

namespace Microsoft.Samples.SqlServer.Workflow.Designer
{
  public class ExpressionEditor : IExpressionEditorInstance
  {
    //Create expression editor control to give to workflow designer. This is the controls with the context MenuItem
    ExpressionEditorUserControl control = new ExpressionEditorUserControl();
    
    //Context MenuItem
    private System.Windows.Controls.MenuItem expressionMenu = null;
    
    //Target ModelItem
    private string _expressionPath = string.Empty;
    
    public string ExpressionPath
    {
      get
      {
        return _expressionPath;
      }

      set
      {
        _expressionPath = value;
      }
    }
    public SqlConnectionStringBuilder ConnectionStringBuilder { get; set; }
    public ModelItem ExpressionModelItem { get; set; }
    public ModelItem OwnerActivity { get; set; }
    
    #region Setup HostControl including converters and builders

    //Host expression control
    public System.Windows.Controls.Control HostControl
    {
      get
      {
        control.Loaded += new RoutedEventHandler(control_Loaded);
        control.expressionText.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(expressionText_PreviewKeyDown);                
        control.expressionText.IsVisibleChanged += new DependencyPropertyChangedEventHandler(expressionText_IsVisibleChanged);
        control.expressionText.LostFocus += new RoutedEventHandler(expressionText_LostFocus);
        control.UnloadHost += new EventHandler(control_UnloadHost);

        return control;
      }
    }

    //Load ExpressionMenu
    void control_Loaded(object sender, RoutedEventArgs e)
    {
      if (expressionMenu == null)
      {
        expressionMenu = (System.Windows.Controls.MenuItem)control.expressionMenu.FindName("expressionMenu");
        expressionMenu.Items.Clear();
        expressionMenu.Visibility = Visibility.Visible;

        foreach (string name in this.VariableNames)
        {
            expressionMenu.Items.Add(AddMenuItem(name, name));
        }
      }
    }

    private System.Windows.Controls.MenuItem AddMenuItem(string name, string header)
    {
        System.Windows.Controls.MenuItem menuItem = new System.Windows.Controls.MenuItem();
        menuItem.Name = name;
        menuItem.Header = header;
        menuItem.Click += new System.Windows.RoutedEventHandler(menuItem_Click);

        return menuItem;
    }

    void menuItem_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        this.OnUpdated((sender as System.Windows.Controls.MenuItem).Header.ToString());
    }

    /// <summary>
    /// Model Variables
    /// </summary>
    public List<string> VariableNames
    {
      get
      {
        List<string> values = new List<string>();
        foreach (ModelItem mi in this.Variables)
        {
          values.Add(mi.Properties["Name"].ComputedValue.ToString());
        }
        return values;
      }
    }

    /// <summary>
    /// Update expression from Builder
    /// </summary>
    /// <param name="message"></param>
    private void OnUpdated(object message)
    {
      if (message != null)
        control.expressionText.DocumentText(message.ToString());

      //Commit Expression Text
      this._commitedText = control.expressionText.DocumentText();
      LostAggregateFocus(null, null);
    }

    #endregion

    #region Expression RichTextBox
    void expressionText_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
      if (e.Key == System.Windows.Input.Key.Enter)
      {
        LostAggregateFocus(sender, e);
      }
    }

    //Is visible so set focus to expression RichTextBox
    void expressionText_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      System.Windows.Controls.RichTextBox rt;

      if ((bool)e.NewValue == true)
      {
        rt = sender as System.Windows.Controls.RichTextBox;
        if (this.Text != null)
          rt.DocumentText(this.Text);

        control.expressionText.Focus();
      }
    }
    #endregion

    #region Commit expression
    void control_UnloadHost(object sender, EventArgs e)
    {
      LostAggregateFocus(sender, e);
    }

    void expressionText_LostFocus(object sender, RoutedEventArgs e)
    {
      System.Windows.Controls.RichTextBox rt = sender as System.Windows.Controls.RichTextBox;
      
      this._commitedText = rt.DocumentText();
      LostAggregateFocus(sender, e);
    }

    private string _commitedText = string.Empty;
    public string CommitedText
    {
      get{
        return _commitedText;
      }
      set{
        _commitedText = value;
      }
    }

    public string GetCommittedText()
    {
      return _commitedText;
    }
    #endregion

    #region Implemented Members
    public bool AcceptsReturn { get; set; }
    public bool AcceptsTab { get; set; }
    public bool HasAggregateFocus
    {
      get
      {
        return true;
      }
    }
    public System.Windows.Controls.ScrollBarVisibility HorizontalScrollBarVisibility { get; set; }
    public int MaxLines { get; set; }
    public int MinLines { get; set; }
    public string Text
    {
      get;
      set;
    }
    public System.Windows.Controls.ScrollBarVisibility VerticalScrollBarVisibility { get; set; }
    public event EventHandler Closing;
    public event EventHandler GotAggregateFocus;
    public event EventHandler LostAggregateFocus;
    public event EventHandler TextChanged;
    public bool CanCompleteWord()
    {
      return true;
    }
    public bool CanCopy()
    {
      return true;
    }
    public bool CanCut()
    {
      return true;
    }
    public bool CanDecreaseFilterLevel()
    {
      return true;
    }
    public bool CanGlobalIntellisense()
    {
      return true;
    }
    public bool CanIncreaseFilterLevel()
    {
      return true;
    }
    public bool CanParameterInfo()
    {
      return true;
    }
    public bool CanPaste()
    {
      return true;
    }
    public bool CanQuickInfo()
    {
      return true;
    }
    public bool CanRedo()
    {
      return true;
    }
    public bool CanUndo()
    {
      return true;
    }
    public void ClearSelection()
    {

    }
    public void Close()
    {

    }
    public bool CompleteWord()
    {
      return true;
    }
    public bool Copy()
    {
      return true;
    }
    public bool Cut()
    {
      return true;
    }
    public bool DecreaseFilterLevel()
    {
      return true;
    }
    public void Focus()
    {

    }
    public bool GlobalIntellisense()
    {
      return true;
    }
    public bool IncreaseFilterLevel()
    {
      return true;
    }
    public bool ParameterInfo()
    {
      return true;
    }
    public bool Paste()
    {
      return true;
    }
    public bool QuickInfo()
    {
      return true;
    }
    public bool Redo()
    {
      return true;
    }
    public bool Undo()
    {
      return true;
    }
    #endregion

    public List<ModelItem> Variables
    {
      get;
      set;
    }
    
    public Type ExpressionType
    {
      get;
      set;
    }
  }
}